﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Tulde.MP3tunes;
using WP7.LockerPlayer.ViewModels;
using System.Windows.Threading;
using System.Text;
using System.Windows.Data;
using System.ComponentModel;
using Microsoft.Phone.Shell;
namespace WP7.LockerPlayer
{
    public partial class MediaView : PhoneApplicationPage, INotifyPropertyChanged
    {
        //      public static readonly DependencyProperty ShowPausedProperty = DependencyProperty.RegisterAttached(
        //"ShowPaused",
        //typeof(System.Windows.Visibility),
        //typeof(MediaView), null);
        //      public static readonly DependencyProperty ShowPlayProperty = DependencyProperty.RegisterAttached(
        //"ShowPlay",
        //typeof(System.Windows.Visibility),
        //typeof(MediaView), null);
        //      public static void SetShowPaused(UIElement element, System.Windows.Visibility value)
        //      {
        //          element.SetValue(ShowPaused, value);


        //      }
        //      public static System.Windows.Visibility GetShowPaused(UIElement element)
        //      {
        //          return (System.Windows.Visibility)element.GetValue(ShowPaused);
        //      }
        //      public static void SetShowPlay(UIElement element, System.Windows.Visibility value)
        //      {
        //          element.SetValue(ShowPlay, value);


        //      }
        //      public static System.Windows.Visibility GetShowPlay(UIElement element)
        //      {
        //          return (System.Windows.Visibility)element.GetValue(ShowPlay);
        //      }


        private double currentVolume;
        private bool isMuted = false;
        private bool _isPaused = false;
        private bool isPaused
        {
            get
            {
                return this._isPaused;
            }
            set
            {
                this._isPaused = value;
              
            }
        }

        DispatcherTimer timer;
        #region Properties
        protected TrackViewModel CurrentTrack
        {
            get
            {
                return MainViewModel.Instance.MediaPlayer.NowPlaying;
            }
            set
            {
                MainViewModel.Instance.MediaPlayer.NowPlaying = value;
            }
        }
        protected int CurrentTrackIndex
        {
            get
            {
                return MainViewModel.Instance.MediaPlayer.CurrentIndex;
            }
            set
            {
                MainViewModel.Instance.MediaPlayer.CurrentIndex = value;
          
        #endregion
          }
        }

        public MediaView()
        {
            this.DataContext = MainViewModel.Instance;
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MediaView_Loaded);
            this.isPaused = false;
            this.ToggleMediaButtonGrid(false);
            this.backgroundAlbumArt.ImageOpened += new EventHandler<RoutedEventArgs>(backgroundAlbumArt_ImageOpened);
          
         

        }

        private void ToggleMediaButtonGrid(bool state)
        {
            if (state)
            {
                mediaButtonGrid.Visibility = System.Windows.Visibility.Visible;
            }
            else
            {
                mediaButtonGrid.Visibility = System.Windows.Visibility.Collapsed ;
            }
        }
        private void ToggleMediaButtonState()
        {
            if (this.isPaused)
            {
                this.play.Visibility = System.Windows.Visibility.Visible;
                this.pause.Visibility = System.Windows.Visibility.Collapsed;
                
            }
            else
            {
                this.play.Visibility = System.Windows.Visibility.Collapsed;
                this.pause.Visibility = System.Windows.Visibility.Visible;
            }
          
        }
       
        void MediaView_Loaded(object sender, RoutedEventArgs e)
        {

        }
        private void ToggleProgress(bool state)
        {
            this.progressInd.IsIndeterminate = state;
        }
        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);
            MainViewModel.Instance.MediaPlayer.CurrentPlaylist = null;
            PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Enabled;
            SystemTray.IsVisible = false;
        }
        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {

            this.isPaused = false;
            base.OnNavigatedTo(e);
            string view = this.NavigationContext.QueryString["view"];
            switch (view)
            {
                case "album":
                    MainViewModel.Instance.MediaPlayer.CurrentAlbums = new System.Collections.ObjectModel.ObservableCollection<ViewModels.AlbumViewModel>();
                    this.ToggleAlbumsListEventHandlers(false);
                    MainViewModel.Instance.Albums.Where(x => x.ArtistId ==
                        MainViewModel.Instance.MediaPlayer.CurrentArtist.ArtistId).CopyToObservableCollection(MainViewModel.Instance.MediaPlayer.CurrentAlbums);
                    this.SetActiveView(MediaViewItem.Albums);
                    this.ToggleAlbumsListEventHandlers(true);
                    break;
                case "tracks":
                    this.ToggleNowPlayingEventHandlers(false);
                    MainViewModel.Instance.MediaPlayer.CurrentAlbums = new System.Collections.ObjectModel.ObservableCollection<AlbumViewModel>();
                    MainViewModel.Instance.Albums.Where(x => x.ArtistId ==
                 MainViewModel.Instance.MediaPlayer.CurrentArtist.ArtistId).CopyToObservableCollection(MainViewModel.Instance.MediaPlayer.CurrentAlbums);
                    this.ToggleProgress(true);
                    MainViewModel.Instance.LoadAlbumsTracks(callback =>
                        {
                            this.SetActiveView(MediaViewItem.NowPlaying);
                            this.ToggleProgress(false);
                            this.ToggleNowPlayingEventHandlers(true);
                        }, MainViewModel.Instance.MediaPlayer.CurrentAlbum.AlbumId, MainViewModel.Instance.MediaPlayer.CurrentAlbum.ArtistId);
                    break;
                case "playlist":
                    this.ToggleProgress(true);
                    MainViewModel.Instance.LoadPlaylistTracks(callback =>
                    {
                        this.SetActiveView(MediaViewItem.NowPlaying);
                        this.ToggleProgress(false);

                    }, MainViewModel.Instance.MediaPlayer.CurrentPlaylist.PlaylistId);
                    break;
            }
        }

        private void ToggleAlbumsListEventHandlers(bool state)
        {
            if (state)
            {
                this.albumsList.SelectionChanged += new SelectionChangedEventHandler(albumsList_SelectionChanged);
            }
            else
            {
                this.albumsList.SelectionChanged -= new SelectionChangedEventHandler(albumsList_SelectionChanged);
            }
        }

        private void ToggleNowPlayingEventHandlers(bool state)
        {
            if (state)
            {
                this.nowplayingListBox.SelectionChanged += new SelectionChangedEventHandler(nowplayingListBox_SelectionChanged);
            }
            else
            {
                this.nowplayingListBox.SelectionChanged -= new SelectionChangedEventHandler(nowplayingListBox_SelectionChanged);
            }
        }
        private void ToggleMediaControls(bool state)
        {
            this.MediaControls.Visibility = state ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
        }
        #region ListBox Event Handlers
    
        private void albumsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.albumsList.SelectedItem == null)
                return;
            this.ToggleProgress(true);
            this.ToggleNowPlayingEventHandlers(false);
            MainViewModel.Instance.MediaPlayer.CurrentAlbum = this.albumsList.SelectedItem as AlbumViewModel;
            MainViewModel.Instance.MediaPlayer.NowPlaying = null;
            MainViewModel.Instance.MediaPlayer.CurrentIndex = -1;
            MainViewModel.Instance.LoadAlbumsTracks(callback =>
            {
                this.SetActiveView(MediaViewItem.NowPlaying);
                this.ToggleProgress(false);
                this.ToggleNowPlayingEventHandlers(true);
                if (MainViewModel.Instance.MediaPlayer.CurrentAlbums.Any())
                {
                    MainViewModel.Instance.MediaPlayer.CurrentIndex = 0;
                    MainViewModel.Instance.MediaPlayer.NowPlaying = MainViewModel.Instance.MediaPlayer.CurrentTracks[0];
                    this.SetDisplayBackground();
                }
            }, MainViewModel.Instance.MediaPlayer.CurrentAlbum.AlbumId,
               MainViewModel.Instance.MediaPlayer.CurrentAlbum.ArtistId);
        }

        private void playlistsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.playlistsListBox.SelectedItem == null)
                return;

            this.ToggleProgress(true);
            this.ToggleNowPlayingEventHandlers(false);
            MainViewModel.Instance.MediaPlayer.CurrentPlaylist = this.playlistsListBox.SelectedItem as PlaylistViewModel;
            MainViewModel.Instance.LoadPlaylistTracks(callback =>
            {
                this.SetActiveView(MediaViewItem.NowPlaying);
                this.ToggleProgress(false);
                this.ToggleNowPlayingEventHandlers(true);

            }, MainViewModel.Instance.MediaPlayer.CurrentPlaylist.PlaylistId);

        }

        private void nowplayingListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //this event will fire if we add/remove items.  So if there is no selectied item, return.
            if (this.nowplayingListBox.SelectedItem == null)
                return;

            this.ToggleProgress(true);
            TrackViewModel track = this.nowplayingListBox.SelectedItem as TrackViewModel;
            MainViewModel.Instance.MediaPlayer.NowPlaying = track;
            MainViewModel.Instance.MediaPlayer.CurrentIndex = this.nowplayingListBox.SelectedIndex;

            if (MainViewModel.Instance.MediaPlayer.CurrentPlaylist != null)
            {
                MainViewModel.Instance.MediaPlayer.CurrentArtist = MainViewModel.Instance.Artists.Single(x => x.ArtistName == track.ArtistName);
                this.ToggleAlbumsListEventHandlers(false);
                MainViewModel.Instance.Albums.Where(x => x.ArtistId ==
             MainViewModel.Instance.MediaPlayer.CurrentArtist.ArtistId).CopyToObservableCollection(MainViewModel.Instance.MediaPlayer.CurrentAlbums);
                this.SetDisplayBackground();
                this.ToggleProgress(false);
                this.ToggleAlbumsListEventHandlers(true);

            }
            else
            {

                this.ToggleProgress(false);
            }
            this.Play();

        }
        #endregion
       
        private void SetActiveView(MediaViewItem item)
        {
            try
            {

                this.mediaPivot.SelectedIndex = (int)item;
                if (item == MediaViewItem.NowPlaying)
                {
                    ToggleMediaControls(true);
                }
                else
                {
                    ToggleMediaControls(false);
                }

            }
            catch
            {

            }
        }
        private void SetDisplayBackground()
        {
            /**
             * <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
                <Image Margin="4" Source="YourImageURL" Stretch="None" >                                              
                </Image>
                <Border BorderBrush="Red" BorderThickness="5" CornerRadius="10" >
                </Border>
            </Grid>
             * */


           // ImageBrush backgroundBrush = null;
             this.backgroundAlbumArt.Source = AlbumArtResource.Load(MainViewModel.Instance.MediaPlayer.NowPlaying.AlbumId, AlbumArtSizeOptions.large);
             this.translationTransform.X = 0;
             this.translationTransform.Y = this.backgroundAlbumArt.Height+1;
           
          
            this.backgroundAlbumArtReflected.Source = this.backgroundAlbumArt.Source;

            //this.backgroundAlbumArt.Clip = new RectangleGeometry
            //{
            //    RadiusX = 15,
            //    RadiusY = 15,
            //    Rect = new Rect(0, 0,this.backgroundAlbumArt.ActualWidth,this.backgroundAlbumArt.ActualHeight)
            //};
        
           // backgroundBrush = new ImageBrush();
           // backgroundBrush.ImageSource = AlbumArtResource.Load(MainViewModel.Instance.MediaPlayer.NowPlaying.AlbumId, AlbumArtSizeOptions.large);

           //// backgroundBrush.Opacity = 0.45;
           // backgroundBrush.Stretch = Stretch.UniformToFill;
           // backgroundBrush.AlignmentX = AlignmentX.Center;
           // backgroundBrush.AlignmentY = AlignmentY.Center;
           // this.mediaPivot.Background = backgroundBrush;
         
            
          
           // RadialGradientBrush opacityMask = new RadialGradientBrush();
           // opacityMask.GradientStops.Add(new GradientStop{ Color = Color.FromArgb(255, 0, 0, 0), Offset= 0.0 } );
           // opacityMask.GradientStops.Add(new GradientStop{ Color =Color.FromArgb(0, 0, 0, 0), Offset=  0.55} );
           // opacityMask.GradientStops.Add(new GradientStop{ Color =Color.FromArgb(255, 0, 0, 0), Offset= 0.65} );
           // opacityMask.GradientStops.Add(new GradientStop{ Color =Color.FromArgb(0, 0, 0, 0), Offset=  0.75} );
           // opacityMask.GradientStops.Add(new GradientStop{ Color =Color.FromArgb(255, 0, 0, 0), Offset=  0.80} );
           // opacityMask.GradientStops.Add(new GradientStop{ Color =Color.FromArgb(0, 0, 0, 0), Offset=  0.90} );
           // opacityMask.GradientStops.Add(new GradientStop { Color = Color.FromArgb(255, 0, 0, 0), Offset = 1.0 });
           // ////this.albumArt.Source = AlbumArtResource.Load(new Album { AlbumId = track.AlbumId });

           // backgroundBrush.SetValue(OpacityMaskProperty, opacityMask);

        }

        void backgroundAlbumArt_ImageOpened(object sender, RoutedEventArgs e)
        {
           
        }

        private void player_MediaEnded(object sender, RoutedEventArgs e)
        {
            this.Next();
        }

        private void player_MediaFailed(object sender, ExceptionRoutedEventArgs e)
        {
            PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
        }

        private void player_MediaOpened(object sender, RoutedEventArgs e)
        {
            PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
            SystemTray.IsVisible = true;
            this.isPaused = false;
            if (this.timer == null)
            {
                this.timer = new DispatcherTimer();
                this.timer.Tick += new EventHandler(timer_Tick);
            }
            // this.buttonPanel.Visibility = System.Windows.Visibility.Visible;

            if (this.player.NaturalDuration.HasTimeSpan)
            {
                TimeSpan ts = this.player.NaturalDuration.TimeSpan;
                seekBar.Maximum = ts.TotalSeconds;
                seekBar.SmallChange = 1;
                seekBar.LargeChange = Math.Min(10, ts.Seconds / 10);
                this.status.Text = "Playing " + this.CurrentTrack.TrackTitle;
                //     this.OnTrackPlay(this.CurrentTrack);
            }
            //if (!this.IsFirstPlay)
            //{


            //    // timer.Start();

            //    this.status.Text = "Playing " + this.CurrentTrack.TrackTitle;

            //}
            //else
            //{
            //    this.IsFirstPlay = false;
            //    this.player.Pause();
            //    this.player.Play();
            //    this.status.Text = "Playing " + this.CurrentTrack.TrackTitle;
            //    this.OnTrackPlay(this.CurrentTrack);
            //}


            if (this.player.NaturalDuration.HasTimeSpan)
            {
                // this.durationTxt.Text = string.Format("{0:mm\\:ss}", player.NaturalDuration.TimeSpan);
                this.durationTxt.Text = this.FormatTime(player.NaturalDuration.TimeSpan); // String.Format("{0}:{1}", player.NaturalDuration.TimeSpan.Minutes, player.NaturalDuration.TimeSpan.Seconds);
                timer.Start();
            }
        }

        void timer_Tick(object sender, EventArgs e)
        {
            //if (!isDragging)
            //{
            //    seekBar.Value = this.player.Position.TotalSeconds;
            //}
            this.Dispatcher.BeginInvoke(new Action(() =>
            {

                var p = this.player.Position;
                this.seekBar.Value = this.player.Position.TotalSeconds;
                this.elapsedTxt.Text = this.FormatTime(p);// String.Format("{0}:{1}", p.Minutes, p.Seconds);
                //this.status.Text = this.FormatTime(p);// String.Format("{0}:{1}", p.Minutes, p.Seconds);
            }));
        }

        #region MediaElement Operations
        public void Play()
        {
            this.ToggleMediaButtonGrid(true);
            if (!Microsoft.Xna.Framework.Media.MediaPlayer.GameHasControl)
            {
                MessageBoxResult result = MessageBox.Show("Media is currently playing in the background.  Continuing will stop all background media.  Continue?", "User Action Required", MessageBoxButton.OKCancel);
                if (result == MessageBoxResult.Cancel)
                {
                    return;
                }

            }
            if (!this.isPaused)
            {

                LockerPlayerService s = new LockerPlayerService();
                Uri uri = s.CreateServiceEndpoint(LockerStorageOperations.lockerPlay, new PlayerServiceParameters
                {
                    FileFormat = "mp3",
                    Bitrate = Bitrate.b96000,
                    FileKey = this.CurrentTrack.TrackFileKey,
                    FileName = this.CurrentTrack.TrackTitle + ".mp3"

                });
             
                this.player.Stop();
                this.status.Text = "Loading " + this.CurrentTrack.TrackTitle;
                this.player.Source = uri;
                this.player.Play();
            }
            else
            {
                this.isPaused = false;
                this.timer.Start();
         
                //this.play.Visibility = System.Windows.Visibility.Collapsed;
                //this.pause.Visibility = System.Windows.Visibility.Visible;
                this.status.Text = "Playing " + this.CurrentTrack.TrackTitle;
                this.player.Play();
            }
            this.ToggleMediaButtonState();
        }


        public void Stop()
        {
            this.timer.Stop();
            //this.SetProgressBar(false);
            //this.play.Visibility = System.Windows.Visibility.Visible;
            //this.pause.Visibility = System.Windows.Visibility.Collapsed;
            this.player.Stop();
        }
        public void Pause()
        {
            //this.SetProgressBar(false);
            this.timer.Stop();
            this.status.Text = "Paused " + this.CurrentTrack.TrackTitle;
            //this.play.Visibility = System.Windows.Visibility.Visible;
            //this.pause.Visibility = System.Windows.Visibility.Collapsed;
            this.isPaused = true;
            this.ToggleMediaButtonState();
            this.player.Pause();
            
        }
        public void Next()
        {
            MainViewModel.Instance.MediaPlayer.SetNextTrack();
            //this.CurrentTrackIndex++;
            //if (this.CurrentTrackIndex >= this.TrackCollection.Count)
            //    this.CurrentTrackIndex = 0;
            this.timer.Stop();
            if( MainViewModel.Instance.MediaPlayer.NowPlaying != null)
                this.nowplayingListBox.SetValue(ListBox.SelectedItemProperty, MainViewModel.Instance.MediaPlayer.NowPlaying);
           
            //this.Play();
        }
        public void Previous()
        {
            MainViewModel.Instance.MediaPlayer.SetPreviousTrack();
            //this.CurrentTrackIndex--;
            //if (this.CurrentTrackIndex <= 0)
            //    this.CurrentTrackIndex = 0;
            this.timer.Stop();
            if (MainViewModel.Instance.MediaPlayer.NowPlaying != null)
                this.nowplayingListBox.SetValue(ListBox.SelectedItemProperty, MainViewModel.Instance.MediaPlayer.NowPlaying);
          
            //this.Play();

        }
        public void Mute()
        {
            if (this.isMuted)
            {
                // this.volume.Value = this.currentVolume;
                this.player.Volume = this.currentVolume;
                this.isMuted = false;
            }
            else
            {

                this.currentVolume = this.player.Volume;
                this.isMuted = true;
                //this.volume.Value = 0;
                this.player.Volume = 0;
            }
        }
        private string FormatTime(TimeSpan ts)
        {
            int hour = ts.Hours;
            int minute = ts.Minutes;
            int seconds = ts.Seconds;

            StringBuilder b = new StringBuilder();
            b.Append(hour < 10 ? "0" + hour : hour.ToString());
            b.Append(":");
            b.Append(minute < 10 ? "0" + minute : minute.ToString());
            b.Append(":");
            b.Append(seconds < 10 ? "0" + seconds : seconds.ToString());
            return b.ToString();
        }
        #endregion

        private void previous_Click(object sender, RoutedEventArgs e)
        {
            this.Previous();
        }

        private void play_Click(object sender, RoutedEventArgs e)
        {
            this.Play();
        }

        private void pause_Click(object sender, RoutedEventArgs e)
        {
            this.Pause();
        }

        private void next_Click(object sender, RoutedEventArgs e)
        {
            this.Next();
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }

    public enum MediaViewItem
    {
        NowPlaying = 0,
        Albums = 1,
        Playlist = 2
    }
}